package com.open.capacity.reimburse.service.impl;

import com.open.capacity.model.system.LoginAppUser;
import com.open.capacity.model.system.SysUser;
import com.open.capacity.reimburse.dao.*;
import com.open.capacity.reimburse.entity.*;
import com.open.capacity.reimburse.exception.BusinessException;
import com.open.capacity.reimburse.service.*;
import com.open.capacity.reimburse.util.uuid.UUIDUtils;
import com.open.capacity.user.service.SysAreaService;
import com.open.capacity.user.service.SysUserRelationService;
import com.open.capacity.user.service.SysUserService;
import com.open.capacity.utils.DateUtil;
import com.open.capacity.utils.IdGenerator;
import com.open.capacity.utils.SysUserUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.open.capacity.commons.PageResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.open.capacity.commons.CodeEnum;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.MapUtils;

import org.springframework.util.Assert;


@Service
public class BillApprovalCostServiceImpl implements BillApprovalCostService {

    @Autowired
    private BillApprovalCostDao billDao;
    @Autowired
    private BillApprovalCostPayitemDao payitemDao;
    @Autowired
    private BillApprovalCostPayitemFormDao formDao;
    @Autowired
    private BasePayItemFormService basePayItemFormService;
    @Autowired
    private BillRouteService routeService;

    @Autowired
    private BillApprovalCostSettlementDao settlementDao;
    @Autowired
    private BillApprovalCostSettlementItemDao settlementItemDao;

    @Autowired
    private BillAttachService attachService;

    @Autowired
    private StdHotelService stdHotelService;

    @Autowired
    private StdMealAllowanceService stdMealAllowanceService;

    @Autowired
    private StdTrafficAllowanceService stdTrafficAllowanceService;

    @Autowired
    private StdTrafficService stdTrafficService;
    @Autowired
    private SysUserService userService;

    @Autowired
    private SysAreaService areaService;

    @Autowired
    private SysUserRelationService relationService;

    @Override
    public int verifyBill(BillApprovalCost bill) {
        String errorMsg = verify(bill);
        if (StringUtils.isNotEmpty(errorMsg)) {
            throw new BusinessException(errorMsg);
        }
        return 1;
    }

    /**
     * 添加
     *
     * @param bill
     */
    public int save(BillApprovalCost bill, Integer force) {
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();
        if (force != 1) {
            //规则校验
            String errorMsg = verify(bill);
            if (StringUtils.isNotEmpty(errorMsg)) {
                throw new BusinessException(errorMsg);
            }
        }
        bill.setCode("D" + DateUtil.dateTimeNow() + IdGenerator.next("direct", 6));
        bill.setStatus(1);
        bill.setCreateTime(new Date());
        bill.setCreateUserid(loginUser.getId());
        bill.setCreateUsername(loginUser.getRealName());

        SysUser user = userService.findById(bill.getUserid());
        Assert.notNull(user, "找不到报销人信息");
        bill.setUsername(user.getRealName());
        bill.setCompanyId(loginUser.getCompanyId());

        BigDecimal amount = BigDecimal.ZERO;
        //支出事项
        for (BillApprovalCostPayitem payitem : bill.getPayitemList()) {
            payitem.setId(UUIDUtils.getOriginalUUIDWithoutBar());
            payitem.setBillId(bill.getId());
            amount = amount.add(payitem.getAmount());
            payitemDao.save(payitem);

            //支出事项标准
            if (CollectionUtils.isNotEmpty(payitem.getForms())) {
                for (BillApprovalCostPayitemForm form : payitem.getForms()) {
                    form.setId(UUIDUtils.getOriginalUUIDWithoutBar());
                    form.setPayitemId(payitem.getId());
                    form.setBillId(bill.getId());
                    formDao.save(form);
                }
            }
        }

        //行程
        if (CollectionUtils.isNotEmpty(bill.getRouteList())) {
            for (BillRoute route : bill.getRouteList()) {
                route.setBillId(bill.getId());
                route.setCompanyId(loginUser.getCompanyId());
                route.setDepartmentId(loginUser.getDepartmentId());
                routeService.save(route);
            }
        }

        //附件
        if (CollectionUtils.isNotEmpty(bill.getAttachList())) {
            for (BillAttach attach : bill.getAttachList()) {
                attach.setBillId(bill.getId());
                attach.setCreateUserid(loginUser.getId());
                attach.setCreateUsername(loginUser.getRealName());
                attach.setCreateTime(new Date());
                attachService.save(attach);
            }
        }

        //结算方式
        if (CollectionUtils.isNotEmpty(bill.getSettlementList())) {
            for (BillApprovalCostSettlement settlement : bill.getSettlementList()) {
                settlement.setId(UUIDUtils.getOriginalUUIDWithoutBar());
                settlement.setBillId(bill.getId());
                settlementDao.save(settlement);

                //结算方式-收款人
                if (CollectionUtils.isNotEmpty(settlement.getPayeeList())) {
                    for (BillApprovalCostSettlementItem item : settlement.getPayeeList()) {
                        item.setId(UUIDUtils.getOriginalUUIDWithoutBar());
                        item.setSettlementId(settlement.getId());
                        item.setBillId(bill.getId());
                        settlementItemDao.save(item);
                    }
                }
            }
        }

        bill.setAmount(amount);
        int count = billDao.save(bill);
        return count;
    }

    /**
     * 修改
     *
     * @param bill
     */
    public int update(BillApprovalCost bill, Integer force) {
        LoginAppUser loginUser = SysUserUtil.getLoginAppUser();
        if (force != 1) {
            //规则校验
            String errorMsg = verify(bill);
            if (StringUtils.isNotEmpty(errorMsg)) {
                throw new BusinessException(errorMsg);
            }
        }
        bill.setUpdateTime(new Date());
        bill.setUpdateUserid(loginUser.getId());
        bill.setUpdateUsername(loginUser.getRealName());

        SysUser user = userService.findById(bill.getUserid());
        Assert.notNull(user, "找不到报销人信息");
        bill.setUsername(user.getRealName());
        bill.setCompanyId(loginUser.getCompanyId());

        BigDecimal amount = BigDecimal.ZERO;


        //支出事项
        payitemDao.deleteByBillId(bill.getId());
        formDao.deleteByBillId(bill.getId());
        for (BillApprovalCostPayitem payitem : bill.getPayitemList()) {
            payitem.setId(UUIDUtils.getOriginalUUIDWithoutBar());
            payitem.setBillId(bill.getId());
            amount = amount.add(payitem.getAmount());
            payitemDao.save(payitem);

            //支出事项标准
            if (CollectionUtils.isNotEmpty(payitem.getForms())) {
                for (BillApprovalCostPayitemForm form : payitem.getForms()) {
                    form.setId(UUIDUtils.getOriginalUUIDWithoutBar());
                    form.setPayitemId(payitem.getId());
                    form.setBillId(bill.getId());
                    formDao.save(form);
                }
            }
        }

        //行程
        routeService.deleteByBillId(bill.getId());
        if (CollectionUtils.isNotEmpty(bill.getRouteList())) {
            for (BillRoute route : bill.getRouteList()) {
                route.setBillId(bill.getId());
                route.setCompanyId(loginUser.getCompanyId());
                route.setDepartmentId(loginUser.getDepartmentId());
                routeService.save(route);
            }
        }

        //附件
        attachService.deleteByBillId(bill.getId());
        if (CollectionUtils.isNotEmpty(bill.getAttachList())) {
            for (BillAttach attach : bill.getAttachList()) {
                attach.setBillId(bill.getId());
                attach.setCreateUserid(loginUser.getId());
                attach.setCreateUsername(loginUser.getRealName());
                attach.setCreateTime(new Date());
                attachService.save(attach);
            }
        }

        //结算方式
        settlementDao.deleteByBillId(bill.getId());
        settlementItemDao.deleteByBillId(bill.getId());
        if (CollectionUtils.isNotEmpty(bill.getSettlementList())) {
            for (BillApprovalCostSettlement settlement : bill.getSettlementList()) {
                settlement.setId(UUIDUtils.getOriginalUUIDWithoutBar());
                settlement.setBillId(bill.getId());
                settlementDao.save(settlement);

                //结算方式-收款人
                if (CollectionUtils.isNotEmpty(settlement.getPayeeList())) {
                    for (BillApprovalCostSettlementItem item : settlement.getPayeeList()) {
                        item.setId(UUIDUtils.getOriginalUUIDWithoutBar());
                        item.setSettlementId(settlement.getId());
                        item.setBillId(bill.getId());
                        settlementItemDao.save(item);
                    }
                }
            }
        }

        bill.setAmount(amount);
        int count = billDao.update(bill);
        return count;
    }


    /**
     * 删除
     *
     * @param id
     */
    public int delete(String id) {
        return billDao.delete(id);
    }

    /**
     * 查询记录
     *
     * @param id
     * @return
     */
    public BillApprovalCost findById(String id) {
        BillApprovalCost bill = billDao.findById(id);
        if (bill != null) {
            List<BillApprovalCostPayitem> payitemList = payitemDao.findByBillId(id);
            payitemList.forEach(t -> {
                        List<BillApprovalCostPayitemForm> forms = formDao.findByPayitemId(t.getId());
                        forms.forEach(f -> {
                            f.setForm(basePayItemFormService.findById(f.getFormId()));
                        });
                        t.setForms(forms);
                    }
            );
            bill.setPayitemList(payitemList);
            bill.setRouteList(routeService.findByBillId(id));
            bill.setAttachList(attachService.findByBillId(id));

            // 结算方式
            List<BillApprovalCostSettlement> settlementList = settlementDao.findByBillId(id);
            settlementList.forEach(t -> {
                        List<BillApprovalCostSettlementItem> payeeList = settlementItemDao.findBySettlementId(t.getId());
                        t.setPayeeList(payeeList);
                    }
            );
            bill.setSettlementList(settlementList);
        }
        return bill;
    }

    /**
     * 分页
     *
     * @param params
     * @return
     */
    public PageResult<BillApprovalCost> pageAll(Map<String, Object> params) {
        //设置分页信息，分别是当前页数和每页显示的总记录数【记住：必须在mapper接口中的方法执行之前设置该分页信息】
        if (MapUtils.getInteger(params, "page") != null && MapUtils.getInteger(params, "limit") != null)
            PageHelper.startPage(MapUtils.getInteger(params, "page"), MapUtils.getInteger(params, "limit"), true);

        List<BillApprovalCost> list = billDao.findAll(params);
        PageInfo<BillApprovalCost> pageInfo = new PageInfo(list);

        return PageResult.<BillApprovalCost>builder().data(pageInfo.getList()).resp_code(CodeEnum.SUCCESS.getCode()).count(pageInfo.getTotal()).build();
    }

    /**
     * 列表
     *
     * @param params
     * @return
     */
    public List<BillApprovalCost> findAll(Map<String, Object> params) {
        return billDao.findAll(params);
    }

    //数据校验
    public String verify(BillApprovalCost bill) {
        String errorMsg = "";
        String userId = bill.getUserid();
        String destination = "";//目的地
        Date startTime = new Date();//开始时间
        Date endTime = new Date();//结束时间
        String followUserids = ""; //随行人员

//        Map<String, List<BillApprovalCost>> mapCost = null;//bill.getCostList().stream().collect(Collectors.groupingBy(item -> item.getItemCode(), HashMap::new, Collectors.toList()));
//        int personCounts = (StringUtil.isEmpty(followUserids) ? 0 : followUserids.split(",").length) + 1;
//        for (Map.Entry entry_item : mapCost.entrySet()) {
//            switch (entry_item.getKey().toString()) {
//                case "1": //住宿费校验
//                    errorMsg += stdHotelService.verify(userId, followUserids, personCounts, destination, startTime, endTime, ((List<BillApprovalCost>) entry_item.getValue()).stream().map(e -> e.getMoney()).reduce(BigDecimal.ZERO, BigDecimal::add));
//                    break;
//                case "2": //机票费
//                    errorMsg += stdTrafficService.verify(userId, followUserids, TrafficTypes.PLANE, ((List<BillApprovalCost>) entry_item.getValue()).stream().map(e -> e.getMoney()).reduce(BigDecimal.ZERO, BigDecimal::add));
//                    break;
//                case "4": //伙食补贴校验
//                    errorMsg += stdMealAllowanceService.verify(userId, followUserids, personCounts, destination, startTime, endTime, ((List<BillBusinesstrip2Cost>) entry_item.getValue()).stream().map(e -> e.getMoney()).reduce(BigDecimal.ZERO, BigDecimal::add));
//                    break;
//                case "5": //市内交通补贴校验
//                    errorMsg += stdTrafficAllowanceService.verify(userId, followUserids, personCounts, destination, startTime, endTime, ((List<BillBusinesstrip2Cost>) entry_item.getValue()).stream().map(e -> e.getMoney()).reduce(BigDecimal.ZERO, BigDecimal::add));
//                    break;
//            }
//        }

        return errorMsg;
    }
}
